#include "qb_base_impl.h"
#include <core/QbLogger.h>
#include <core/sharedata/login_data.h>
#include "qbmessage/include/message_kernel.h"
#include "qbmessage/include/message_process.h"
#include "qbmessage/include/message_sync.h"
#include "qbmessage/include/message_bond.h"

namespace qb
{
	static qbBaseImpl* s = nullptr;
	static scoped_refptr<INetworkService>	m_spNetworkService	= NULL;		// 网络
	static scoped_refptr<IMessageKernel>	m_spMessageKernel	= NULL;     // 消息中心
	static scoped_refptr<IMessageProcess>	m_spMessageProcess	= NULL;		// 消息处理模块
	static scoped_refptr<IMessageSync>		m_spMessageSync		= NULL;		// 消息同步模块
	static scoped_refptr<IMessageBond>		m_spMessageBond		= NULL;		// 债券

	qbBase* qbBase::getInterface()
	{
		if (s == nullptr)
		{
			s = new qbBaseImpl();
		}
		
		return s;
	}

	scoped_refptr<IMessageKernel> qbBase::getMessageKernel()
	{
		QB_CHECK_RETURN_VALUE_ASSERT(s, NULL);

		if (!m_spMessageKernel)
		{
			if (0 != s->QueryInterface(CLSID_MessageKernel, IID_IMessageKernel, (void**)&m_spMessageKernel))
			{
				return NULL;
			}
		}

		return m_spMessageKernel;
	}

	scoped_refptr<IMessageProcess> qbBase::getMessageProcess()
	{
		QB_CHECK_RETURN_VALUE_ASSERT(s, NULL);

		if (!m_spMessageProcess)
		{
			if (0 != s->QueryInterface(CLSID_MessageKernel, IID_IMessageProcess, (void**)&m_spMessageProcess))
			{
				return NULL;
			}
		}

		return m_spMessageProcess;
	}

	scoped_refptr<IMessageBond> qbBase::getMessageBond()
	{
		QB_CHECK_RETURN_VALUE_ASSERT(s, NULL);

		if (!m_spMessageBond)
		{
			if (0 != s->QueryInterface(CLSID_MessageKernel, IID_IMessageBond, (void**)&m_spMessageBond))
			{
				return NULL;
			}
		}

		return m_spMessageBond;
	}

	scoped_refptr<IMessageSync> qbBase::getMessageSync()
	{
		QB_CHECK_RETURN_VALUE_ASSERT(s, NULL);

		if (!m_spMessageSync)
		{
			if (0 != s->QueryInterface(CLSID_MessageKernel, IID_IMessageSync, (void**)&m_spMessageSync))
			{
				return NULL;
			}
		}

		return m_spMessageSync;
	}

	scoped_refptr<INetworkService> qbBase::getNetworkService()
	{
		QB_CHECK_RETURN_VALUE_ASSERT(s, NULL);

		if (!m_spNetworkService)
		{
			if (0 != s->QueryInterface(CLSID_NetworkService, IID_INetworkService, (void**)&m_spNetworkService))
			{
				return NULL;
			}
		}

		return m_spNetworkService;
	}

	qbBaseImpl::qbBaseImpl()
	{
	}

	qbBaseImpl::~qbBaseImpl()
	{
		DestroyQbModule();
	}

	int32_t qbBaseImpl::init(const char* exepath)
	{
		if (m_modules.LoadResource(exepath) == -1)
		{
			log_error("load resource failed");
			return -1;
		}

		CreateQbModule();
		return 0;
	}

	int32_t qbBaseImpl::terminate()
	{
		DestroyQbModule();
		
		if (m_modules.UnloadResource() == -1)
		{
			log_warning("unload resource failed");
			return -1;
		}

		return 0;
	}

	int32_t qbBaseImpl::QueryInterface(REFCLSID rclsid, REFIID riid, void** ppv)
	{
		return m_modules.QueryInterface(rclsid, riid, ppv);
	}

	void qbBaseImpl::CreateQbModule()
	{
		InitModule_NetworkService();
		InitModule_MessageProcessor();
	}

	void qbBaseImpl::InitModule_NetworkService()
	{
		if (!m_spNetworkService)
		{
			if (0 != QueryInterface(CLSID_NetworkService, IID_INetworkService, (void**)&m_spNetworkService))
			{
				return;
			}
		}
	}

	void qbBaseImpl::InitModule_MessageProcessor()
	{
		if (!m_spMessageSync)
		{
			if (0 != QueryInterface(CLSID_MessageKernel, IID_IMessageSync, (void**)&m_spMessageSync))
			{
				return;
			}
			if (!m_spMessageSync || !m_spMessageSync->Create())
				return;
		}

		if (!m_spMessageProcess)
		{
			if (0 != QueryInterface(CLSID_MessageKernel, IID_IMessageProcess, (void**)&m_spMessageProcess))
			{
				return;
			}
			if (!m_spMessageProcess)
			{
				return;
			}
			if (0 != m_spMessageProcess->Create(m_spNetworkService, m_spMessageSync))
			{
				return;
			}
		}

		if (!m_spMessageKernel)
		{
			if (-1 == QueryInterface(CLSID_MessageKernel, IID_IMessageKernel, (void**)&m_spMessageKernel))
			{
				return;
			}
			if (!m_spMessageKernel)
			{
				return;
			}
			if (0 != m_spMessageKernel->Create(m_spNetworkService, m_spMessageSync, m_spMessageProcess))
			{
				return;
			}
		}

		if (!m_spMessageBond)
		{
			if (0 != QueryInterface(CLSID_MessageKernel, IID_IMessageBond, (void**)&m_spMessageBond))
			{
				return;
			}
			if (!m_spMessageBond)
			{
				return;
			}
			if (0 != m_spMessageBond->Create(m_spNetworkService, m_spMessageKernel, m_spMessageProcess))
			{
				return;
			}
		}
	}

	void qbBaseImpl::UnInitModule_NetworkService()
	{
		m_spNetworkService = NULL;
	}

	void qbBaseImpl::UnInitModule_MessageProcessor()
	{
		if (m_spMessageBond)
		{
			m_spMessageBond->Destory();
			m_spMessageBond = NULL;
		}
		if (m_spMessageKernel)
		{
			m_spMessageKernel->Destory();
			m_spMessageKernel = NULL;
		}
		if (m_spMessageProcess)
		{
			m_spMessageProcess->Destory();
			m_spMessageProcess = NULL;
		}

		m_spMessageSync = NULL;
	}

	void qbBaseImpl::DestroyQbModule()
	{
		UnInitModule_MessageProcessor();
		UnInitModule_NetworkService();
	}

	scoped_refptr<INetworkService> qbBaseImpl::getNetworkService()
	{
		if (!m_spNetworkService)
		{
			if (0 != QueryInterface(CLSID_NetworkService, IID_INetworkService, (void**)&m_spNetworkService))
			{
				return NULL;
			}
		}

		return m_spNetworkService;
	}
}  // namespace qb
